import { type RemoveMethods } from "@/types/remove-methods";
import { FinishStage, FinishStageList } from "@model/StageFinish";
import { StateMoal } from "@model/StateMoal";
import { TaskList } from "@model/TaskList";
import { FieldContentData } from "@model/fieldTree";
import { StageData, StageList } from "@model/stage";
import { TimeManageList } from "@model/timeManage";
import UseCacheFinishStageMap from "@pinias/UseCacheFinishStageMap";
import UseCacheIdStatMap from "@pinias/UseCacheIdStatMap";
import UseFieldTree from "@pinias/UseFieldTree";
import UseLifeModel from "@pinias/UseLifeModel";
import UseSetting from "@pinias/UseSetting";
import UseStage from "@pinias/UseStage";
import UseTask from "@pinias/UseTask";
import UseTimeManageList from "@pinias/UseTimeManageList";
import pinia from "@pinias/pinia";
import { DateTimeStr, getEndOfDay, getstartOfDay, timestampToDateTime } from "@utils/DateUtils";
import { picPath, taskLogPath } from "@utils/pathUtils";
import * as PathUtils from "@utils/pathUtils";

const { getTimeManageList } = UseTimeManageList(pinia);
const { getTaskList } = UseTask(pinia);
const { getStageList } = UseStage(pinia);
const { getFileFullPath, getFileBasePath } = UseSetting(pinia);
const { getLifeModel } = UseLifeModel(pinia);
const { getFieldTree } = UseFieldTree(pinia);
const { getCacheFinishStageMap } = UseCacheFinishStageMap(pinia);

export class Location {
  str: string;
  static getLocation() {
    return "暂时获取不了地址";
  }
}

export class TaskLogData {
  id: string;
  type: number;
  taskId: number | undefined;
  startTime: number;
  isMemory: boolean;
  endTime: number;
  markDownFile: string;
  picList: Array<string>;
  mediaList: Array<string>;
  location: Location;

  constructor(
    id: string,
    type: number,
    taskId: number | undefined,
    startTime: number,
    endTime: number,
    location: Location,
    isMemory: boolean,
  ) {
    this.id = id;
    this.type = type;
    this.taskId = taskId;
    this.startTime = startTime;
    this.endTime = endTime;
    this.markDownFile = "";
    this.mediaList = [];
    this.picList = [];
    this.location = location;
    this.isMemory = isMemory;
  }

  static removePath(list: Array<string>, list2: Array<string>) {
    const toRemove = new Array<string>();
    const set = new Set<string>();
    for (let j = 0; j < list2.length; j++) {
      set.add(list2[j]);
    }
    for (let i = 0; i < list.length; i++) {
      const str = list[i];
      if (!set.has(str)) toRemove.push(str);
    }
    return toRemove;
  }
  static async getBaseMediaPath(taskLogData: TaskLogData) {
    // console.log("getFullMediaPath",taskLogData)
    taskLogData.mediaList = await getFileBasePath(taskLogData.mediaList);
    taskLogData.picList = await getFileBasePath(taskLogData.picList);
    // console.log("getFullMediaPath",taskLogData)
    return taskLogData;
  }
  static async getFullMediaPath(taskLogData: TaskLogData) {
    // console.log("getFullMediaPath",taskLogData)
    taskLogData.mediaList = await getFileFullPath(taskLogData.mediaList, picPath);
    taskLogData.picList = await getFileFullPath(taskLogData.picList, picPath);
    //  console.log("getFullMediaPath",taskLogData)
    return taskLogData;
  }
  static async getFatherId(type: number, taskId: number | undefined) {
    const oldFatherId: Array<{ id: number | undefined; name: string }> = [];
    if (taskId !== undefined) {
      if (type === 2) {
        const timeManageList: TimeManageList = getTimeManageList();
        const timeManage = timeManageList.getTimeManageById(taskId);
        if (timeManage !== undefined) {
          oldFatherId.push({ id: taskId, name: timeManage.desc });
          const lifeModel = getLifeModel();
          const life = lifeModel.getLifeModelDataById(timeManage.fatherId);
          if (life !== undefined) oldFatherId.push({ id: timeManage.fatherId, name: life.name });
        } else {
          const lifeModel = getLifeModel();
          const life = lifeModel.getLifeModelDataById(taskId);
          if (life !== undefined) oldFatherId.push({ id: taskId, name: life.name });
        }
      }
      if (type === 1) {
        const taskList = getTaskList();
        const taskDataById = taskList.getTaskDataById(taskId);
        if (taskDataById !== undefined) {
          oldFatherId.push({ id: taskId, name: taskDataById.name });
          const stageList: StageList = getStageList();
          const stage = stageList.getStageDataById(taskDataById.fatherId);
          if (stage !== undefined) {
            oldFatherId.push({ id: stage.id, name: stage.name });
            const fieldTree = getFieldTree();
            const field = fieldTree.getFieldDataById(stage.fatherId);
            if (field !== undefined) oldFatherId.push({ id: field.id, name: field.topic });
          }
        } else {
          // 前往IdSata里面获取
          const cacheIdStatMap = getCacheIdStatMap();
          // const stat = await cacheIdStatMap.getIdStat(taskId);
          const stat = await cacheIdStatMap.getIdStatNotCreate(taskId);
          // console.log(stat,"++++++++++++++++++++++")
          let findFlag = false;
          if (stat !== undefined && stat.fatherId > 0) {
            const stageList: StageList = getStageList();
            const stage = stageList.getStageDataById(stat.fatherId);
            if (stage !== undefined) {
              const fieldId = stage.fatherId;
              const cacheFinishStageMap = getCacheFinishStageMap();
              const finishStageList = await cacheFinishStageMap.getFinishStageList(fieldId);
              const finishStage = FinishStageList.getFinishStage(finishStageList, stage.id);
              if (finishStage !== undefined) {
                findFlag = true;
                const taskData = FinishStage.getTaskData(finishStage, taskId);
                if (taskData !== undefined) oldFatherId.push({ id: taskId, name: taskData.name });
                oldFatherId.push({ id: stage.id, name: stage.name });
                const fieldTree = getFieldTree();
                const field = fieldTree.getFieldDataById(stage.fatherId);
                if (field !== undefined) oldFatherId.push({ id: field.id, name: field.topic });
              }
            }
          }
          if (!findFlag) {
            const stageList: StageList = getStageList();
            const stage = stageList.getStageDataById(taskId);
            // console.log(stage,"++++++++++++++++++++++")
            if (stage !== undefined) {
              oldFatherId.push({ id: stage.id, name: stage.name });
              const fieldTree = getFieldTree();
              const field = fieldTree.getFieldDataById(stage.fatherId);
              if (field !== undefined) oldFatherId.push({ id: field.id, name: field.topic });
            } else {
              const fieldTree = getFieldTree();
              const field = fieldTree.getFieldDataById(taskId);
              if (field !== undefined) oldFatherId.push({ id: field.id, name: field.topic });
            }
          }
        }
      }
    }
    return oldFatherId;
  }
  static getTypeOptions() {
    return [
      {
        label: "领域阶段任务",
        value: 1,
      },
      {
        label: "生活模式任务",
        value: 2,
      },
    ];
  }
  static getNullModel() {
    return new TaskLogData("", 1, 0, new Date().getTime(), new Date().getTime(), new Location(), false);
  }
  static copyLogData(tosave: TaskLogData) {
    const taskdLogData = new TaskLogData(
      tosave.id,
      tosave.type,
      tosave.taskId,
      tosave.startTime,
      tosave.endTime,
      tosave.location,
      tosave.isMemory,
    );
    taskdLogData.markDownFile = tosave.markDownFile;
    taskdLogData.mediaList = [...tosave.mediaList];
    taskdLogData.picList = [...tosave.picList];
    return taskdLogData;
  }
}
const { getCacheIdStatMap } = UseCacheIdStatMap(pinia);
export class TaskLogMap {
  key: string; // 202307
  taskLogMap: Map<string, TaskLogData>; // 20230723003406:modal
  everyDayLogMap: Map<string, Array<string>>; // 20230723:[20230723003406,...]
  constructor(timeStamp: number) {
    const dateTimeStr = new DateTimeStr(timeStamp);
    this.key = dateTimeStr.getMonthInfo();
    this.taskLogMap = new Map<string, TaskLogData>();
    this.everyDayLogMap = new Map<string, Array<string>>();
  }
  static addTaskLogData(taskLogMap: TaskLogMap, taskLogData: TaskLogData) {
    taskLogMap.taskLogMap.set(taskLogData.id, taskLogData);
    const dayKey = taskLogData.id.slice(0, 8);
    let dayList = taskLogMap.everyDayLogMap.get(dayKey);
    if (dayList === undefined) {
      dayList = new Array<string>();
      taskLogMap.everyDayLogMap.set(dayKey, dayList);
    }
    dayList.push(taskLogData.id);
    // const monthKey = taskLogData.id.slice(0, 6);
    // let monthList = taskLogMap.everyMonthMap.get(monthKey);
    // if (monthList === undefined) {
    //   monthList = new Array<string>();
    //   taskLogMap.everyMonthMap.set(monthKey, monthList);
    // }
    // if (monthList.find(i => i === dayKey) === undefined) monthList.push(dayKey);
  }
  static getLogPath(timeStamp: number) {
    const dateTimeStr = new DateTimeStr(timeStamp);
    return {
      path: taskLogPath + dateTimeStr.getMonthInfo() + ".json",
      key: dateTimeStr.getMonthInfo(),
    };
  }
}
const { getCacheModel } = UseSetting(pinia);
export class CacheTaskLogMap {
  cacheTaskLogList: Array<string>; // 202307.json
  cacheTaskLogMap: Map<string, TaskLogMap>; // 202307:TaskLogMap
  changeKeys: Array<string>; // 202307,...

  setInfo(data: RemoveMethods<CacheTaskLogMap>) {
    Object.assign(this, data);
  }
  constructor(cacheTaskLogList: Array<string>, cacheTaskLogMap: Map<string, TaskLogMap>, changeKeys: Array<string>) {
    this.cacheTaskLogList = cacheTaskLogList;
    this.cacheTaskLogMap = cacheTaskLogMap;
    this.changeKeys = changeKeys;
  }
  async deleteTaskLogData(ids: Array<string | undefined>) {
    const changeKey = new Set<string>();
    for (const id of ids) {
      // console.log(id,"++++++++++++++++++++")
      if (id !== undefined) {
        const timeStamp = DateTimeStr.getTimeStamp(id);
        const taskLogMap = await this.getTaskLogMap(timeStamp);
        taskLogMap.taskLogMap.delete(id);
        const dayKey = id.slice(0, 8);
        let dayList = taskLogMap.everyDayLogMap.get(dayKey);
        if (dayList !== undefined) {
          dayList = dayList.filter(value => value !== id);
          taskLogMap.everyDayLogMap.set(dayKey, dayList);
        }
        changeKey.add(taskLogMap.key);
      }
    }
    if (changeKey.size > 0) this.changeKeys.push(...changeKey);
    // console.log(this.changeKeys,changeKey,"++++++++++++++++++++")
  }
  async addTaskLogData(tosaveList: Array<TaskLogData> | undefined) {
    console.log("++++++++++++++++++++", tosaveList);
    if (tosaveList === undefined || tosaveList.length !== 1) return "";
    const taskLogData = tosaveList[0];
    // 开始时间需要需小于结束时间
    if (taskLogData.startTime >= taskLogData.endTime) return "开始时间需要需小于结束时间";
    if (taskLogData.endTime - taskLogData.startTime < 60 * 1000 * 3) return "结束时间需要大于开始时间3分钟";
    if (taskLogData.endTime - taskLogData.startTime >= 60 * 1000 * 60 * 24) return "结束时间不可大于开始时间24小时";
    // 如果开始时间和结束时间不在用一天，分成两个taskLog进行记录
    const startDateTimeStr = new DateTimeStr(taskLogData.startTime);
    const endDateTimeStr = new DateTimeStr(taskLogData.endTime);
    const check = taskLogData.id.slice(0, 8);
    if (startDateTimeStr.getDayInfo() !== check && endDateTimeStr.getDayInfo() !== check)
      return "编辑时，不可以将记录开始时间和结束时间都改到其他日期";
    // console.log("++++++++++++++++++++", startDateTimeStr.getDayInfo(), endDateTimeStr.getDayInfo());
    if (startDateTimeStr.getDayInfo() !== endDateTimeStr.getDayInfo()) {
      const taskLogData1 = TaskLogData.copyLogData(taskLogData);
      const taskLogData2 = TaskLogData.copyLogData(taskLogData);
      taskLogData1.endTime = getEndOfDay(taskLogData.startTime); // startDateTimeStr.getEndOfDayTimeStamp();
      taskLogData2.startTime = getstartOfDay(taskLogData.endTime); //endDateTimeStr.getStartOfDayTimeStamp();
      if (startDateTimeStr.getDayInfo() === check) {
        taskLogData1.id = taskLogData.id;
        taskLogData2.id = new DateTimeStr(taskLogData2.startTime).getTimeInfo();
      }
      if (endDateTimeStr.getDayInfo() === check) {
        taskLogData2.id = taskLogData.id;
        taskLogData1.id = new DateTimeStr(taskLogData1.startTime).getTimeInfo();
      }
      tosaveList.pop();
      tosaveList.push(taskLogData1);
      tosaveList.push(taskLogData2);
      // console.log("++++++++++++++++++++", tosaveList);
    }
    const changeKey: Array<string> = [];
    // console.log("tosaveList",tosaveList)
    for (let i = 0; i < tosaveList.length; i++) {
      const tosave = tosaveList[i];
      const dayKey = tosave.id.slice(0, 8);
      const logTimeStamp = DateTimeStr.getTimeStamp(tosave.id);
      let newTaskLogMap: TaskLogMap = new TaskLogMap(logTimeStamp);
      // console.log("tosaveList",dayKey,logTimeStamp)
      newTaskLogMap = await getCacheModel(
        PathUtils.taskLogPath + newTaskLogMap.key + ".json",
        newTaskLogMap.key,
        this.cacheTaskLogMap,
        newTaskLogMap,
      );
      const dayList = newTaskLogMap.everyDayLogMap.get(dayKey);
      if (dayList !== undefined && dayList.length > 0) {
        let index = -1;
        let lastIndex = -1;
        let nextIndex = -1;
        dayList.forEach((value, i) => {
          if (value === taskLogData.id) {
            index = i;
            lastIndex = i - 1;
            if (i + 1 < dayList.length) nextIndex = i + 1;
          }
        });
        if (index === -1) {
          // 添加情况
          for (let j = 0; j < dayList.length; j++) {
            lastIndex = j - 1;
            const log = newTaskLogMap.taskLogMap.get(dayList[j]);
            // console.log(j,"+++++++++++++++++",log)
            if (log !== undefined && log.endTime > tosave.startTime) {
              nextIndex = j;
              break;
            }
          }
          if (nextIndex === -1) lastIndex += 1;
        }
        // console.log(index,lastIndex,nextIndex)
        if (lastIndex !== -1) {
          // 有上一条记录
          const lastLog = newTaskLogMap.taskLogMap.get(dayList[lastIndex]);
          if (lastLog !== undefined && lastLog.endTime > tosave.startTime)
            return "开始时间不可在上一任务记录的结束时间之前：" + timestampToDateTime(lastLog.endTime);
        }
        if (nextIndex !== -1 && nextIndex < dayList.length) {
          // 有下一条记录
          const lastLog = newTaskLogMap.taskLogMap.get(dayList[nextIndex]);
          if (lastLog !== undefined && lastLog.startTime < tosave.endTime)
            return "结束时间不可超过下一任务记录的开始时间之后：" + timestampToDateTime(lastLog.startTime);
        }
        if (index === -1) {
          // const newDayList = new Array<string>();
          // 添加情况
          if (nextIndex === -1) {
            dayList.push(tosave.id);
          } else dayList.splice(nextIndex, 0, tosave.id);
        }
      } else {
        // 说明没有任务，直接加入dayList
        const newDayList = new Array<string>();
        newDayList.push(tosave.id);
        newTaskLogMap.everyDayLogMap.set(dayKey, newDayList);
      }
      newTaskLogMap.taskLogMap.set(tosave.id, tosave);
      changeKey.push(newTaskLogMap.key);
    }
    this.changeKeys = changeKey;
    // console.log("addTaskLogData", this);
    return "";
  }
  async getTaskLogMap(endTime: number) {
    // 获取数据库记录，：如果超过年份，则创建文件
    const key = TaskLogMap.getLogPath(endTime);
    let newTaskLogMap = new TaskLogMap(endTime);
    // console.log(endTime)
    newTaskLogMap = await getCacheModel(key.path, key.key, this.cacheTaskLogMap, newTaskLogMap);
    return newTaskLogMap;
  }
  async getTaskLogData(id: string) {
    const timeStamp = DateTimeStr.getTimeStamp(id);
    const taskLogMap = await this.getTaskLogMap(timeStamp);
    const taskLogData = taskLogMap.taskLogMap.get(id);
    // if (taskLogData !== undefined) {
    //   const copy = TaskLogData.copyLogData(taskLogData);
    //   if (fullMediaPath) return await TaskLogData.getFullMediaPath(copy);
    //   else return copy;
    // }
    return taskLogData;
  }
  async getStageSelectOptions2(fieldData: FieldContentData | undefined, hasFinish: boolean, stageList: StageList) {
    const result = [];
    if (fieldData !== undefined) {
      const stateMoal = fieldData.stageIds;
      const list = new Set<number>();
      StateMoal.getAllId(stateMoal, list, true, true, false);
      for (let i = 0; i < stageList.stageData.length; i++) {
        const data = stageList.stageData[i];
        if (list.has(data.id)) {
          result.push({
            label: data.name,
            value: data.id,
          });
        }
      }
      if (hasFinish) {
        const cacheFinishStageMap = getCacheFinishStageMap();
        const finishStageList = await cacheFinishStageMap.getFinishStageList(fieldData.id);
        if (finishStageList.finishStageList.length > 0) {
          for (const finishStageListElement of finishStageList.finishStageList) {
            result.push({
              label: finishStageListElement.name,
              value: finishStageListElement.id,
            });
          }
        }
      }
    }
    return result;
  }
  async getTaskSelectOptions2(stageData: StageData | undefined, hasFinish: boolean, taskList: TaskList) {
    const result = [];
    if (stageData !== undefined) {
      if (!stageData.finished) {
        const task = stageData.task;
        const list = new Set<number>();
        StateMoal.getAllId(task.TaskBased, list, true, true, true);
        StateMoal.getAllId(task.ClockBased, list, true, true, true);
        for (let i = 0; i < taskList.taskData.length; i++) {
          const data = taskList.taskData[i];
          if (list.has(data.id)) {
            result.push({
              label: data.name,
              value: data.id,
            });
          }
        }
      }
      if (hasFinish && stageData.finished) {
        const cacheFinishStageMap = getCacheFinishStageMap();
        const finishStageList = await cacheFinishStageMap.getFinishStageList(stageData.fatherId);
        const finishStage = FinishStageList.getFinishStage(finishStageList, stageData.id);
        if (finishStage !== undefined) {
          let tasks = FinishStage.getTaskDataList(finishStage, 1);
          for (const task of tasks) {
            result.push({
              label: task.name,
              value: task.id,
            });
          }
          tasks = FinishStage.getTaskDataList(finishStage, 2);
          for (const task of tasks) {
            result.push({
              label: task.name,
              value: task.id,
            });
          }
        }
      }
    }

    return result;
  }
}
